﻿using BootstrapAdmin.DataAccess.Models;
using BootstrapAdmin.DataAccess.Models.Production;
using BootstrapAdmin.Web.Core.Models;
using BootstrapAdmin.Web.Core.Services;
using PetaPoco;

namespace BootstrapAdmin.DataAccess.PetaPoco.Services;

internal sealed class ArchiveService : IArchiveService
{
    private readonly IDBManager _dbManager;

    public ArchiveService(IDBManager db) => _dbManager = db;

    public async Task<ApiResult> SaveArchiveAsync(ApiData data)
    {
        var sn = data.GetValue<string>("PLC_Archive_SN");
        var pass = data.GetValue<int>("PLC_Archive_Pass");
        var ct = data.GetValue<int>("PLC_Archive_Cycletime");
        var @operator = data.GetValue<string>("PLC_Archive_Operator");
        var shift = data.GetValue<int>("PLC_Archive_Shift");
        var pallet = data.GetValue<string>("PLC_Archive_Pallet");

        if (string.IsNullOrWhiteSpace(sn))
        {
            return ApiResult.Error(ErrorCode.ErrEmptyOfSN);
        }

        // 记录进站信息
        using var db = _dbManager.Create();
        try
        {
            // 按位解析
            Sql sql1 = new();
            sql1.Where("Category = @0 AND Code = @1", "Shift", shift);
            var shiftDict = await db.FirstOrDefaultAsync<DictInfo>(sql1);

            db.BeginTransaction();

            // 主数据
            Archive archive = new()
            {
                Station = data.Schema.Station,
                OrderNo = "", // 从业务中获取，SN 反查订单
                ProductCode = "", // 程序配方号找到对应的产品编号
                SN = sn,
                Pass = pass,
                Cycletime = ct,
                Operator = @operator,
                Shift = shiftDict?.Name ?? shift.ToString(),
                Pallet = pallet,
                CreatedAt = DateTime.Now,
            };
            var id = (ulong)await db.InsertAsync(archive);

            // 明细数据
            foreach (var item in data.Values.Where(s => s.IsAdditional))
            {
                ArchiveItem item0 = new()
                {
                    ArchiveId = (int)id,
                    Tag = item.Tag,
                    Name = item.Name ?? "",
                    Value = item.GetValue<string>(),
                    IsArray = item.IsArray(),
                };

                await db.InsertAsync(item0);
            }

            Sql sql2 = new();
            sql2.Where("Station = @0", data.Schema.Station);
            var prodStation = await db.FirstOrDefaultAsync<ProductionStation>(sql2);
            if (prodStation == null)
            {
                prodStation = new()
                {
                    Station = data.Schema.Station,
                    CurrentOrderNo = "",
                    CurrentSN = sn,
                    CompletedQty = 1,
                    QualifiedQty = 1,
                };
                await db.InsertAsync(prodStation);
            }
            else
            {
                // 还需校验重复存档的数据。
                var completedQty = prodStation.CompletedQty + 1;
                var qualifiedQty = prodStation.QualifiedQty + 1;
                await db.UpdateAsync<ProductionStation>("SET CurrentSN = @0, CompletedQty = @1, QualifiedQty = @2 WHERE Id = @3", 
                    sn,
                    completedQty,
                    qualifiedQty,
                    prodStation.Id);
            }

            db.CompleteTransaction();
        }
        catch(Exception ex)
        {
            db.AbortTransaction();
            return ApiResult.Error(ex.Message);
        }

        return ApiResult.Ok();
    }
}
